1   /*
2    * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package com.sun.media.sound;
26  
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.util.HashSet;
30  import java.util.Iterator;
31  import java.util.Set;
32  import java.util.TreeMap;
33  import java.util.Map.Entry;
34  
35  import javax.sound.midi.MidiMessage;
36  import javax.sound.midi.Patch;
37  import javax.sound.midi.ShortMessage;
38  import javax.sound.sampled.AudioInputStream;
39  import javax.sound.sampled.AudioSystem;
40  
41  /**
42   * Software synthesizer main audio mixer.
43   *
44   * @author Karl Helgason
45   */
46  public class SoftMainMixer {
47  
48      // A private class thats contains a ModelChannelMixer and it's private buffers.
49      // This becomes necessary when we want to have separate delay buffers for each channel mixer.
50      private class SoftChannelMixerContainer
51      {
52          ModelChannelMixer mixer;
53          SoftAudioBuffer[] buffers;
54      }
55  
56      public final static int CHANNEL_LEFT = 0;
57      public final static int CHANNEL_RIGHT = 1;
58      public final static int CHANNEL_MONO = 2;
59      public final static int CHANNEL_DELAY_LEFT = 3;
60      public final static int CHANNEL_DELAY_RIGHT = 4;
61      public final static int CHANNEL_DELAY_MONO = 5;
62      public final static int CHANNEL_EFFECT1 = 6;
63      public final static int CHANNEL_EFFECT2 = 7;
64      public final static int CHANNEL_DELAY_EFFECT1 = 8;
65      public final static int CHANNEL_DELAY_EFFECT2 = 9;
66      public final static int CHANNEL_LEFT_DRY = 10;
67      public final static int CHANNEL_RIGHT_DRY = 11;
68      public final static int CHANNEL_SCRATCH1 = 12;
69      public final static int CHANNEL_SCRATCH2 = 13;
70      protected boolean active_sensing_on = false;
71      private long msec_last_activity = -1;
72      private boolean pusher_silent = false;
73      private int pusher_silent_count = 0;
74      private long sample_pos = 0;
75      protected boolean readfully = true;
76      private Object control_mutex;
77      private SoftSynthesizer synth;
78      private float samplerate = 44100;
79      private int nrofchannels = 2;
80      private SoftVoice[] voicestatus = null;
81      private SoftAudioBuffer[] buffers;
82      private SoftReverb reverb;
83      private SoftAudioProcessor chorus;
84      private SoftAudioProcessor agc;
85      private long msec_buffer_len = 0;
86      private int buffer_len = 0;
87      protected TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>();
88      private int delay_midievent = 0;
89      private int max_delay_midievent = 0;
90      double last_volume_left = 1.0;
91      double last_volume_right = 1.0;
92      private double[] co_master_balance = new double[1];
93      private double[] co_master_volume = new double[1];
94      private double[] co_master_coarse_tuning = new double[1];
95      private double[] co_master_fine_tuning = new double[1];
96      private AudioInputStream ais;
97      private Set<SoftChannelMixerContainer> registeredMixers = null;
98      private Set<ModelChannelMixer> stoppedMixers = null;
99      private SoftChannelMixerContainer[] cur_registeredMixers = null;
100     protected SoftControl co_master = new SoftControl() {
101 
102         double[] balance = co_master_balance;
103         double[] volume = co_master_volume;
104         double[] coarse_tuning = co_master_coarse_tuning;
105         double[] fine_tuning = co_master_fine_tuning;
106 
107         public double[] get(int instance, String name) {
108             if (name == null)
109                 return null;
110             if (name.equals("balance"))
111                 return balance;
112             if (name.equals("volume"))
113                 return volume;
114             if (name.equals("coarse_tuning"))
115                 return coarse_tuning;
116             if (name.equals("fine_tuning"))
117                 return fine_tuning;
118             return null;
119         }
120     };
121 
122     private void processSystemExclusiveMessage(byte[] data) {
123         synchronized (synth.control_mutex) {
124             activity();
125 
126             // Universal Non-Real-Time SysEx
127             if ((data[1] & 0xFF) == 0x7E) {
128                 int deviceID = data[2] & 0xFF;
129                 if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
130                     int subid1 = data[3] & 0xFF;
131                     int subid2;
132                     switch (subid1) {
133                     case 0x08:  // MIDI Tuning Standard
134                         subid2 = data[4] & 0xFF;
135                         switch (subid2) {
136                         case 0x01:  // BULK TUNING DUMP
137                         {
138                             // http://www.midi.org/about-midi/tuning.shtml
139                             SoftTuning tuning = synth.getTuning(new Patch(0,
140                                     data[5] & 0xFF));
141                             tuning.load(data);
142                             break;
143                         }
144                         case 0x04:  // KEY-BASED TUNING DUMP
145                         case 0x05:  // SCALE/OCTAVE TUNING DUMP, 1 byte format
146                         case 0x06:  // SCALE/OCTAVE TUNING DUMP, 2 byte format
147                         case 0x07:  // SINGLE NOTE TUNING CHANGE (NON REAL-TIME)
148                                     // (BANK)
149                         {
150                             // http://www.midi.org/about-midi/tuning_extens.shtml
151                             SoftTuning tuning = synth.getTuning(new Patch(
152                                     data[5] & 0xFF, data[6] & 0xFF));
153                             tuning.load(data);
154                             break;
155                         }
156                         case 0x08:  // scale/octave tuning 1-byte form (Non
157                                     // Real-Time)
158                         case 0x09:  // scale/octave tuning 2-byte form (Non
159                                     // Real-Time)
160                         {
161                             // http://www.midi.org/about-midi/tuning-scale.shtml
162                             SoftTuning tuning = new SoftTuning(data);
163                             int channelmask = (data[5] & 0xFF) * 16384
164                                     + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
165                             SoftChannel[] channels = synth.channels;
166                             for (int i = 0; i < channels.length; i++)
167                                 if ((channelmask & (1 << i)) != 0)
168                                     channels[i].tuning = tuning;
169                             break;
170                         }
171                         default:
172                             break;
173                         }
174                         break;
175                     case 0x09:  // General Midi Message
176                         subid2 = data[4] & 0xFF;
177                         switch (subid2) {
178                         case 0x01:  // General Midi 1 On
179                             synth.setGeneralMidiMode(1);
180                             reset();
181                             break;
182                         case 0x02:  // General Midi Off
183                             synth.setGeneralMidiMode(0);
184                             reset();
185                             break;
186                         case 0x03:  // General MidI Level 2 On
187                             synth.setGeneralMidiMode(2);
188                             reset();
189                             break;
190                         default:
191                             break;
192                         }
193                         break;
194                     case 0x0A: // DLS Message
195                         subid2 = data[4] & 0xFF;
196                         switch (subid2) {
197                         case 0x01:  // DLS On
198                             if (synth.getGeneralMidiMode() == 0)
199                                 synth.setGeneralMidiMode(1);
200                             synth.voice_allocation_mode = 1;
201                             reset();
202                             break;
203                         case 0x02:  // DLS Off
204                             synth.setGeneralMidiMode(0);
205                             synth.voice_allocation_mode = 0;
206                             reset();
207                             break;
208                         case 0x03:  // DLS Static Voice Allocation Off
209                             synth.voice_allocation_mode = 0;
210                             break;
211                         case 0x04:  // DLS Static Voice Allocation On
212                             synth.voice_allocation_mode = 1;
213                             break;
214                         default:
215                             break;
216                         }
217                         break;
218 
219                     default:
220                         break;
221                     }
222                 }
223             }
224 
225             // Universal Real-Time SysEx
226             if ((data[1] & 0xFF) == 0x7F) {
227                 int deviceID = data[2] & 0xFF;
228                 if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
229                     int subid1 = data[3] & 0xFF;
230                     int subid2;
231                     switch (subid1) {
232                     case 0x04: // Device Control
233 
234                         subid2 = data[4] & 0xFF;
235                         switch (subid2) {
236                         case 0x01: // Master Volume
237                         case 0x02: // Master Balane
238                         case 0x03: // Master fine tuning
239                         case 0x04: // Master coarse tuning
240                             int val = (data[5] & 0x7F)
241                                     + ((data[6] & 0x7F) * 128);
242                             if (subid2 == 0x01)
243                                 setVolume(val);
244                             else if (subid2 == 0x02)
245                                 setBalance(val);
246                             else if (subid2 == 0x03)
247                                 setFineTuning(val);
248                             else if (subid2 == 0x04)
249                                 setCoarseTuning(val);
250                             break;
251                         case 0x05: // Global Parameter Control
252                             int ix = 5;
253                             int slotPathLen = (data[ix++] & 0xFF);
254                             int paramWidth = (data[ix++] & 0xFF);
255                             int valueWidth = (data[ix++] & 0xFF);
256                             int[] slotPath = new int[slotPathLen];
257                             for (int i = 0; i < slotPathLen; i++) {
258                                 int msb = (data[ix++] & 0xFF);
259                                 int lsb = (data[ix++] & 0xFF);
260                                 slotPath[i] = msb * 128 + lsb;
261                             }
262                             int paramCount = (data.length - 1 - ix)
263                                     / (paramWidth + valueWidth);
264                             long[] params = new long[paramCount];
265                             long[] values = new long[paramCount];
266                             for (int i = 0; i < paramCount; i++) {
267                                 values[i] = 0;
268                                 for (int j = 0; j < paramWidth; j++)
269                                     params[i] = params[i] * 128
270                                             + (data[ix++] & 0xFF);
271                                 for (int j = 0; j < valueWidth; j++)
272                                     values[i] = values[i] * 128
273                                             + (data[ix++] & 0xFF);
274 
275                             }
276                             globalParameterControlChange(slotPath, params, values);
277                             break;
278                         default:
279                             break;
280                         }
281                         break;
282 
283                     case 0x08:  // MIDI Tuning Standard
284                         subid2 = data[4] & 0xFF;
285                         switch (subid2) {
286                         case 0x02:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
287                         {
288                             // http://www.midi.org/about-midi/tuning.shtml
289                             SoftTuning tuning = synth.getTuning(new Patch(0,
290                                     data[5] & 0xFF));
291                             tuning.load(data);
292                             SoftVoice[] voices = synth.getVoices();
293                             for (int i = 0; i < voices.length; i++)
294                                 if (voices[i].active)
295                                     if (voices[i].tuning == tuning)
296                                         voices[i].updateTuning(tuning);
297                             break;
298                         }
299                         case 0x07:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
300                                     // (BANK)
301                         {
302                             // http://www.midi.org/about-midi/tuning_extens.shtml
303                             SoftTuning tuning = synth.getTuning(new Patch(
304                                     data[5] & 0xFF, data[6] & 0xFF));
305                             tuning.load(data);
306                             SoftVoice[] voices = synth.getVoices();
307                             for (int i = 0; i < voices.length; i++)
308                                 if (voices[i].active)
309                                     if (voices[i].tuning == tuning)
310                                         voices[i].updateTuning(tuning);
311                             break;
312                         }
313                         case 0x08:  // scale/octave tuning 1-byte form
314                                     //(Real-Time)
315                         case 0x09:  // scale/octave tuning 2-byte form
316                                     // (Real-Time)
317                         {
318                             // http://www.midi.org/about-midi/tuning-scale.shtml
319                             SoftTuning tuning = new SoftTuning(data);
320                             int channelmask = (data[5] & 0xFF) * 16384
321                                     + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
322                             SoftChannel[] channels = synth.channels;
323                             for (int i = 0; i < channels.length; i++)
324                                 if ((channelmask & (1 << i)) != 0)
325                                     channels[i].tuning = tuning;
326                             SoftVoice[] voices = synth.getVoices();
327                             for (int i = 0; i < voices.length; i++)
328                                 if (voices[i].active)
329                                     if ((channelmask & (1 << (voices[i].channel))) != 0)
330                                         voices[i].updateTuning(tuning);
331                             break;
332                         }
333                         default:
334                             break;
335                         }
336                         break;
337                     case 0x09:  // Control Destination Settings
338                         subid2 = data[4] & 0xFF;
339                         switch (subid2) {
340                         case 0x01: // Channel Pressure
341                         {
342                             int[] destinations = new int[(data.length - 7) / 2];
343                             int[] ranges = new int[(data.length - 7) / 2];
344                             int ix = 0;
345                             for (int j = 6; j < data.length - 1; j += 2) {
346                                 destinations[ix] = data[j] & 0xFF;
347                                 ranges[ix] = data[j + 1] & 0xFF;
348                                 ix++;
349                             }
350                             int channel = data[5] & 0xFF;
351                             SoftChannel softchannel = synth.channels[channel];
352                             softchannel.mapChannelPressureToDestination(
353                                     destinations, ranges);
354                             break;
355                         }
356                         case 0x02: // Poly Pressure
357                         {
358                             int[] destinations = new int[(data.length - 7) / 2];
359                             int[] ranges = new int[(data.length - 7) / 2];
360                             int ix = 0;
361                             for (int j = 6; j < data.length - 1; j += 2) {
362                                 destinations[ix] = data[j] & 0xFF;
363                                 ranges[ix] = data[j + 1] & 0xFF;
364                                 ix++;
365                             }
366                             int channel = data[5] & 0xFF;
367                             SoftChannel softchannel = synth.channels[channel];
368                             softchannel.mapPolyPressureToDestination(
369                                     destinations, ranges);
370                             break;
371                         }
372                         case 0x03: // Control Change
373                         {
374                             int[] destinations = new int[(data.length - 7) / 2];
375                             int[] ranges = new int[(data.length - 7) / 2];
376                             int ix = 0;
377                             for (int j = 7; j < data.length - 1; j += 2) {
378                                 destinations[ix] = data[j] & 0xFF;
379                                 ranges[ix] = data[j + 1] & 0xFF;
380                                 ix++;
381                             }
382                             int channel = data[5] & 0xFF;
383                             SoftChannel softchannel = synth.channels[channel];
384                             int control = data[6] & 0xFF;
385                             softchannel.mapControlToDestination(control,
386                                     destinations, ranges);
387                             break;
388                         }
389                         default:
390                             break;
391                         }
392                         break;
393 
394                     case 0x0A:  // Key Based Instrument Control
395                     {
396                         subid2 = data[4] & 0xFF;
397                         switch (subid2) {
398                         case 0x01: // Basic Message
399                             int channel = data[5] & 0xFF;
400                             int keynumber = data[6] & 0xFF;
401                             SoftChannel softchannel = synth.channels[channel];
402                             for (int j = 7; j < data.length - 1; j += 2) {
403                                 int controlnumber = data[j] & 0xFF;
404                                 int controlvalue = data[j + 1] & 0xFF;
405                                 softchannel.controlChangePerNote(keynumber,
406                                         controlnumber, controlvalue);
407                             }
408                             break;
409                         default:
410                             break;
411                         }
412                         break;
413                     }
414                     default:
415                         break;
416                     }
417                 }
418             }
419 
420         }
421     }
422 
423     private void processMessages(long timeStamp) {
424         Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator();
425         while (iter.hasNext()) {
426             Entry<Long, Object> entry = iter.next();
427             if (entry.getKey() >= (timeStamp + msec_buffer_len))
428                 return;
429             long msec_delay = entry.getKey() - timeStamp;
430             delay_midievent = (int)(msec_delay * (samplerate / 1000000.0) + 0.5);
431             if(delay_midievent > max_delay_midievent)
432                 delay_midievent = max_delay_midievent;
433             if(delay_midievent < 0)
434                 delay_midievent = 0;
435             processMessage(entry.getValue());
436             iter.remove();
437         }
438         delay_midievent = 0;
439     }
440 
441     protected void processAudioBuffers() {
442 
443         if(synth.weakstream != null && synth.weakstream.silent_samples != 0)
444         {
445             sample_pos += synth.weakstream.silent_samples;
446             synth.weakstream.silent_samples = 0;
447         }
448 
449         for (int i = 0; i < buffers.length; i++) {
450             if(i != CHANNEL_DELAY_LEFT &&
451                     i != CHANNEL_DELAY_RIGHT &&
452                     i != CHANNEL_DELAY_MONO &&
453                     i != CHANNEL_DELAY_EFFECT1 &&
454                     i != CHANNEL_DELAY_EFFECT2)
455                 buffers[i].clear();
456         }
457 
458         if(!buffers[CHANNEL_DELAY_LEFT].isSilent())
459         {
460             buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]);
461         }
462         if(!buffers[CHANNEL_DELAY_RIGHT].isSilent())
463         {
464             buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]);
465         }
466         if(!buffers[CHANNEL_DELAY_MONO].isSilent())
467         {
468             buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]);
469         }
470         if(!buffers[CHANNEL_DELAY_EFFECT1].isSilent())
471         {
472             buffers[CHANNEL_EFFECT1].swap(buffers[CHANNEL_DELAY_EFFECT1]);
473         }
474         if(!buffers[CHANNEL_DELAY_EFFECT2].isSilent())
475         {
476             buffers[CHANNEL_EFFECT2].swap(buffers[CHANNEL_DELAY_EFFECT2]);
477         }
478 
479         double volume_left;
480         double volume_right;
481 
482         SoftChannelMixerContainer[] act_registeredMixers;
483 
484         // perform control logic
485         synchronized (control_mutex) {
486 
487             long msec_pos = (long)(sample_pos * (1000000.0 / samplerate));
488 
489             processMessages(msec_pos);
490 
491             if (active_sensing_on) {
492                 // Active Sensing
493                 // if no message occurs for max 1000 ms
494                 // then do AllSoundOff on all channels
495                 if ((msec_pos - msec_last_activity) > 1000000) {
496                     active_sensing_on = false;
497                     for (SoftChannel c : synth.channels)
498                         c.allSoundOff();
499                 }
500 
501             }
502 
503             for (int i = 0; i < voicestatus.length; i++)
504                 if (voicestatus[i].active)
505                     voicestatus[i].processControlLogic();
506             sample_pos += buffer_len;
507 
508             double volume = co_master_volume[0];
509             volume_left = volume;
510             volume_right = volume;
511 
512             double balance = co_master_balance[0];
513             if (balance > 0.5)
514                 volume_left *= (1 - balance) * 2;
515             else
516                 volume_right *= balance * 2;
517 
518             chorus.processControlLogic();
519             reverb.processControlLogic();
520             agc.processControlLogic();
521 
522             if (cur_registeredMixers == null) {
523                 if (registeredMixers != null) {
524                     cur_registeredMixers =
525                             new SoftChannelMixerContainer[registeredMixers.size()];
526                     registeredMixers.toArray(cur_registeredMixers);
527                 }
528             }
529 
530             act_registeredMixers = cur_registeredMixers;
531             if (act_registeredMixers != null)
532                 if (act_registeredMixers.length == 0)
533                     act_registeredMixers = null;
534 
535         }
536 
537         if (act_registeredMixers != null) {
538 
539             // Make backup of left,right,mono channels
540             SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT];
541             SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT];
542             SoftAudioBuffer monobak = buffers[CHANNEL_MONO];
543             SoftAudioBuffer delayleftbak = buffers[CHANNEL_DELAY_LEFT];
544             SoftAudioBuffer delayrightbak = buffers[CHANNEL_DELAY_RIGHT];
545             SoftAudioBuffer delaymonobak = buffers[CHANNEL_DELAY_MONO];
546 
547             int bufferlen = buffers[CHANNEL_LEFT].getSize();
548 
549             float[][] cbuffer = new float[nrofchannels][];
550             float[][] obuffer = new float[nrofchannels][];
551             obuffer[0] = leftbak.array();
552             if (nrofchannels != 1)
553                 obuffer[1] = rightbak.array();
554 
555             for (SoftChannelMixerContainer cmixer : act_registeredMixers) {
556 
557                 // Reroute default left,right output
558                 // to channelmixer left,right input/output
559                 buffers[CHANNEL_LEFT] =  cmixer.buffers[CHANNEL_LEFT];
560                 buffers[CHANNEL_RIGHT] = cmixer.buffers[CHANNEL_RIGHT];
561                 buffers[CHANNEL_MONO] = cmixer.buffers[CHANNEL_MONO];
562                 buffers[CHANNEL_DELAY_LEFT] = cmixer.buffers[CHANNEL_DELAY_LEFT];
563                 buffers[CHANNEL_DELAY_RIGHT] = cmixer.buffers[CHANNEL_DELAY_RIGHT];
564                 buffers[CHANNEL_DELAY_MONO] = cmixer.buffers[CHANNEL_DELAY_MONO];
565 
566                 buffers[CHANNEL_LEFT].clear();
567                 buffers[CHANNEL_RIGHT].clear();
568                 buffers[CHANNEL_MONO].clear();
569 
570                 if(!buffers[CHANNEL_DELAY_LEFT].isSilent())
571                 {
572                     buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]);
573                 }
574                 if(!buffers[CHANNEL_DELAY_RIGHT].isSilent())
575                 {
576                     buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]);
577                 }
578                 if(!buffers[CHANNEL_DELAY_MONO].isSilent())
579                 {
580                     buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]);
581                 }
582 
583                 cbuffer[0] = buffers[CHANNEL_LEFT].array();
584                 if (nrofchannels != 1)
585                     cbuffer[1] = buffers[CHANNEL_RIGHT].array();
586 
587                 boolean hasactivevoices = false;
588                 for (int i = 0; i < voicestatus.length; i++)
589                     if (voicestatus[i].active)
590                         if (voicestatus[i].channelmixer == cmixer.mixer) {
591                             voicestatus[i].processAudioLogic(buffers);
592                             hasactivevoices = true;
593                         }
594 
595                 if(!buffers[CHANNEL_MONO].isSilent())
596                 {
597                     float[] mono = buffers[CHANNEL_MONO].array();
598                     float[] left = buffers[CHANNEL_LEFT].array();
599                     if (nrofchannels != 1) {
600                         float[] right = buffers[CHANNEL_RIGHT].array();
601                         for (int i = 0; i < bufferlen; i++) {
602                             float v = mono[i];
603                             left[i] += v;
604                             right[i] += v;
605                         }
606                     }
607                     else
608                     {
609                         for (int i = 0; i < bufferlen; i++) {
610                             left[i] += mono[i];
611                         }
612                     }
613                 }
614 
615                 if (!cmixer.mixer.process(cbuffer, 0, bufferlen)) {
616                     synchronized (control_mutex) {
617                         registeredMixers.remove(cmixer);
618                         cur_registeredMixers = null;
619                     }
620                 }
621 
622                 for (int i = 0; i < cbuffer.length; i++) {
623                     float[] cbuff = cbuffer[i];
624                     float[] obuff = obuffer[i];
625                     for (int j = 0; j < bufferlen; j++)
626                         obuff[j] += cbuff[j];
627                 }
628 
629                 if (!hasactivevoices) {
630                     synchronized (control_mutex) {
631                         if (stoppedMixers != null) {
632                             if (stoppedMixers.contains(cmixer)) {
633                                 stoppedMixers.remove(cmixer);
634                                 cmixer.mixer.stop();
635                             }
636                         }
637                     }
638                 }
639 
640             }
641 
642             buffers[CHANNEL_LEFT] = leftbak;
643             buffers[CHANNEL_RIGHT] = rightbak;
644             buffers[CHANNEL_MONO] = monobak;
645             buffers[CHANNEL_DELAY_LEFT] = delayleftbak;
646             buffers[CHANNEL_DELAY_RIGHT] = delayrightbak;
647             buffers[CHANNEL_DELAY_MONO] = delaymonobak;
648 
649         }
650 
651         for (int i = 0; i < voicestatus.length; i++)
652             if (voicestatus[i].active)
653                 if (voicestatus[i].channelmixer == null)
654                     voicestatus[i].processAudioLogic(buffers);
655 
656         if(!buffers[CHANNEL_MONO].isSilent())
657         {
658             float[] mono = buffers[CHANNEL_MONO].array();
659             float[] left = buffers[CHANNEL_LEFT].array();
660             int bufferlen = buffers[CHANNEL_LEFT].getSize();
661             if (nrofchannels != 1) {
662                 float[] right = buffers[CHANNEL_RIGHT].array();
663                 for (int i = 0; i < bufferlen; i++) {
664                     float v = mono[i];
665                     left[i] += v;
666                     right[i] += v;
667                 }
668             }
669             else
670             {
671                 for (int i = 0; i < bufferlen; i++) {
672                     left[i] += mono[i];
673                 }
674             }
675         }
676 
677         // Run effects
678         if (synth.chorus_on)
679             chorus.processAudio();
680 
681         if (synth.reverb_on)
682             reverb.processAudio();
683 
684         if (nrofchannels == 1)
685             volume_left = (volume_left + volume_right) / 2;
686 
687         // Set Volume / Balance
688         if (last_volume_left != volume_left || last_volume_right != volume_right) {
689             float[] left = buffers[CHANNEL_LEFT].array();
690             float[] right = buffers[CHANNEL_RIGHT].array();
691             int bufferlen = buffers[CHANNEL_LEFT].getSize();
692 
693             float amp;
694             float amp_delta;
695             amp = (float)(last_volume_left * last_volume_left);
696             amp_delta = (float)((volume_left * volume_left - amp) / bufferlen);
697             for (int i = 0; i < bufferlen; i++) {
698                 amp += amp_delta;
699                 left[i] *= amp;
700             }
701             if (nrofchannels != 1) {
702                 amp = (float)(last_volume_right * last_volume_right);
703                 amp_delta = (float)((volume_right*volume_right - amp) / bufferlen);
704                 for (int i = 0; i < bufferlen; i++) {
705                     amp += amp_delta;
706                     right[i] *= volume_right;
707                 }
708             }
709             last_volume_left = volume_left;
710             last_volume_right = volume_right;
711 
712         } else {
713             if (volume_left != 1.0 || volume_right != 1.0) {
714                 float[] left = buffers[CHANNEL_LEFT].array();
715                 float[] right = buffers[CHANNEL_RIGHT].array();
716                 int bufferlen = buffers[CHANNEL_LEFT].getSize();
717                 float amp;
718                 amp = (float) (volume_left * volume_left);
719                 for (int i = 0; i < bufferlen; i++)
720                     left[i] *= amp;
721                 if (nrofchannels != 1) {
722                     amp = (float)(volume_right * volume_right);
723                     for (int i = 0; i < bufferlen; i++)
724                         right[i] *= amp;
725                 }
726 
727             }
728         }
729 
730         if(buffers[CHANNEL_LEFT].isSilent()
731             && buffers[CHANNEL_RIGHT].isSilent())
732         {
733 
734             int midimessages_size;
735             synchronized (control_mutex) {
736                 midimessages_size = midimessages.size();
737             }
738 
739             if(midimessages_size == 0)
740             {
741                 pusher_silent_count++;
742                 if(pusher_silent_count > 5)
743                 {
744                     pusher_silent_count = 0;
745                     synchronized (control_mutex) {
746                         pusher_silent = true;
747                         if(synth.weakstream != null)
748                             synth.weakstream.setInputStream(null);
749                     }
750                 }
751             }
752         }
753         else
754             pusher_silent_count = 0;
755 
756         if (synth.agc_on)
757             agc.processAudio();
758 
759     }
760 
761     // Must only we called within control_mutex synchronization
762     public void activity()
763     {
764         long silent_samples = 0;
765         if(pusher_silent)
766         {
767             pusher_silent = false;
768             if(synth.weakstream != null)
769             {
770                 synth.weakstream.setInputStream(ais);
771                 silent_samples = synth.weakstream.silent_samples;
772             }
773         }
774         msec_last_activity = (long)((sample_pos + silent_samples)
775                 * (1000000.0 / samplerate));
776     }
777 
778     public void stopMixer(ModelChannelMixer mixer) {
779         if (stoppedMixers == null)
780             stoppedMixers = new HashSet<ModelChannelMixer>();
781         stoppedMixers.add(mixer);
782     }
783 
784     public void registerMixer(ModelChannelMixer mixer) {
785         if (registeredMixers == null)
786             registeredMixers = new HashSet<SoftChannelMixerContainer>();
787         SoftChannelMixerContainer mixercontainer = new SoftChannelMixerContainer();
788         mixercontainer.buffers = new SoftAudioBuffer[6];
789         for (int i = 0; i < mixercontainer.buffers.length; i++) {
790             mixercontainer.buffers[i] =
791                 new SoftAudioBuffer(buffer_len, synth.getFormat());
792         }
793         mixercontainer.mixer = mixer;
794         registeredMixers.add(mixercontainer);
795         cur_registeredMixers = null;
796     }
797 
798     public SoftMainMixer(SoftSynthesizer synth) {
799         this.synth = synth;
800 
801         sample_pos = 0;
802 
803         co_master_balance[0] = 0.5;
804         co_master_volume[0] = 1;
805         co_master_coarse_tuning[0] = 0.5;
806         co_master_fine_tuning[0] = 0.5;
807 
808         msec_buffer_len = (long) (1000000.0 / synth.getControlRate());
809         samplerate = synth.getFormat().getSampleRate();
810         nrofchannels = synth.getFormat().getChannels();
811 
812         int buffersize = (int) (synth.getFormat().getSampleRate()
813                                 / synth.getControlRate());
814 
815         buffer_len = buffersize;
816 
817         max_delay_midievent = buffersize;
818 
819         control_mutex = synth.control_mutex;
820         buffers = new SoftAudioBuffer[14];
821         for (int i = 0; i < buffers.length; i++) {
822             buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat());
823         }
824         voicestatus = synth.getVoices();
825 
826         reverb = new SoftReverb();
827         chorus = new SoftChorus();
828         agc = new SoftLimiter();
829 
830         float samplerate = synth.getFormat().getSampleRate();
831         float controlrate = synth.getControlRate();
832         reverb.init(samplerate, controlrate);
833         chorus.init(samplerate, controlrate);
834         agc.init(samplerate, controlrate);
835 
836         reverb.setLightMode(synth.reverb_light);
837 
838         reverb.setMixMode(true);
839         chorus.setMixMode(true);
840         agc.setMixMode(false);
841 
842         chorus.setInput(0, buffers[CHANNEL_EFFECT2]);
843         chorus.setOutput(0, buffers[CHANNEL_LEFT]);
844         if (nrofchannels != 1)
845             chorus.setOutput(1, buffers[CHANNEL_RIGHT]);
846         chorus.setOutput(2, buffers[CHANNEL_EFFECT1]);
847 
848         reverb.setInput(0, buffers[CHANNEL_EFFECT1]);
849         reverb.setOutput(0, buffers[CHANNEL_LEFT]);
850         if (nrofchannels != 1)
851             reverb.setOutput(1, buffers[CHANNEL_RIGHT]);
852 
853         agc.setInput(0, buffers[CHANNEL_LEFT]);
854         if (nrofchannels != 1)
855             agc.setInput(1, buffers[CHANNEL_RIGHT]);
856         agc.setOutput(0, buffers[CHANNEL_LEFT]);
857         if (nrofchannels != 1)
858             agc.setOutput(1, buffers[CHANNEL_RIGHT]);
859 
860         InputStream in = new InputStream() {
861 
862             private SoftAudioBuffer[] buffers = SoftMainMixer.this.buffers;
863             private int nrofchannels
864                     = SoftMainMixer.this.synth.getFormat().getChannels();
865             private int buffersize = buffers[0].getSize();
866             private byte[] bbuffer = new byte[buffersize
867                     * (SoftMainMixer.this.synth.getFormat()
868                         .getSampleSizeInBits() / 8)
869                     * nrofchannels];
870             private int bbuffer_pos = 0;
871             private byte[] single = new byte[1];
872 
873             public void fillBuffer() {
874                 /*
875                 boolean pusher_silent2;
876                 synchronized (control_mutex) {
877                     pusher_silent2 = pusher_silent;
878                 }
879                 if(!pusher_silent2)*/
880                 processAudioBuffers();
881                 for (int i = 0; i < nrofchannels; i++)
882                     buffers[i].get(bbuffer, i);
883                 bbuffer_pos = 0;
884             }
885 
886             public int read(byte[] b, int off, int len) {
887                 int bbuffer_len = bbuffer.length;
888                 int offlen = off + len;
889                 int orgoff = off;
890                 byte[] bbuffer = this.bbuffer;
891                 while (off < offlen) {
892                     if (available() == 0)
893                         fillBuffer();
894                     else {
895                         int bbuffer_pos = this.bbuffer_pos;
896                         while (off < offlen && bbuffer_pos < bbuffer_len)
897                             b[off++] = bbuffer[bbuffer_pos++];
898                         this.bbuffer_pos = bbuffer_pos;
899                         if (!readfully)
900                             return off - orgoff;
901                     }
902                 }
903                 return len;
904             }
905 
906             public int read() throws IOException {
907                 int ret = read(single);
908                 if (ret == -1)
909                     return -1;
910                 return single[0] & 0xFF;
911             }
912 
913             public int available() {
914                 return bbuffer.length - bbuffer_pos;
915             }
916 
917             public void close() {
918                 SoftMainMixer.this.synth.close();
919             }
920         };
921 
922         ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED);
923 
924     }
925 
926     public AudioInputStream getInputStream() {
927         return ais;
928     }
929 
930     public void reset() {
931 
932         SoftChannel[] channels = synth.channels;
933         for (int i = 0; i < channels.length; i++) {
934             channels[i].allSoundOff();
935             channels[i].resetAllControllers(true);
936 
937             if (synth.getGeneralMidiMode() == 2) {
938                 if (i == 9)
939                     channels[i].programChange(0, 0x78 * 128);
940                 else
941                     channels[i].programChange(0, 0x79 * 128);
942             } else
943                 channels[i].programChange(0, 0);
944         }
945         setVolume(0x7F * 128 + 0x7F);
946         setBalance(0x40 * 128 + 0x00);
947         setCoarseTuning(0x40 * 128 + 0x00);
948         setFineTuning(0x40 * 128 + 0x00);
949         // Reset Reverb
950         globalParameterControlChange(
951                 new int[]{0x01 * 128 + 0x01}, new long[]{0}, new long[]{4});
952         // Reset Chorus
953         globalParameterControlChange(
954                 new int[]{0x01 * 128 + 0x02}, new long[]{0}, new long[]{2});
955     }
956 
957     public void setVolume(int value) {
958         synchronized (control_mutex) {
959             co_master_volume[0] = value / 16384.0;
960         }
961     }
962 
963     public void setBalance(int value) {
964         synchronized (control_mutex) {
965             co_master_balance[0] = value / 16384.0;
966         }
967     }
968 
969     public void setFineTuning(int value) {
970         synchronized (control_mutex) {
971             co_master_fine_tuning[0] = value / 16384.0;
972         }
973     }
974 
975     public void setCoarseTuning(int value) {
976         synchronized (control_mutex) {
977             co_master_coarse_tuning[0] = value / 16384.0;
978         }
979     }
980 
981     public int getVolume() {
982         synchronized (control_mutex) {
983             return (int) (co_master_volume[0] * 16384.0);
984         }
985     }
986 
987     public int getBalance() {
988         synchronized (control_mutex) {
989             return (int) (co_master_balance[0] * 16384.0);
990         }
991     }
992 
993     public int getFineTuning() {
994         synchronized (control_mutex) {
995             return (int) (co_master_fine_tuning[0] * 16384.0);
996         }
997     }
998 
999     public int getCoarseTuning() {
1000         synchronized (control_mutex) {
1001             return (int) (co_master_coarse_tuning[0] * 16384.0);
1002         }
1003     }
1004 
1005     public void globalParameterControlChange(int[] slothpath, long[] params,
1006             long[] paramsvalue) {
1007         if (slothpath.length == 0)
1008             return;
1009 
1010         synchronized (control_mutex) {
1011 
1012             // slothpath: 01xx are reserved only for GM2
1013 
1014             if (slothpath[0] == 0x01 * 128 + 0x01) {
1015                 for (int i = 0; i < paramsvalue.length; i++) {
1016                     reverb.globalParameterControlChange(slothpath, params[i],
1017                             paramsvalue[i]);
1018                 }
1019             }
1020             if (slothpath[0] == 0x01 * 128 + 0x02) {
1021                 for (int i = 0; i < paramsvalue.length; i++) {
1022                     chorus.globalParameterControlChange(slothpath, params[i],
1023                             paramsvalue[i]);
1024                 }
1025 
1026             }
1027 
1028         }
1029     }
1030 
1031     public void processMessage(Object object) {
1032         if (object instanceof byte[])
1033             processMessage((byte[]) object);
1034         if (object instanceof MidiMessage)
1035             processMessage((MidiMessage)object);
1036     }
1037 
1038     public void processMessage(MidiMessage message) {
1039         if (message instanceof ShortMessage) {
1040             ShortMessage sms = (ShortMessage)message;
1041             processMessage(sms.getChannel(), sms.getCommand(),
1042                     sms.getData1(), sms.getData2());
1043             return;
1044         }
1045         processMessage(message.getMessage());
1046     }
1047 
1048     public void processMessage(byte[] data) {
1049         int status = 0;
1050         if (data.length > 0)
1051             status = data[0] & 0xFF;
1052 
1053         if (status == 0xF0) {
1054             processSystemExclusiveMessage(data);
1055             return;
1056         }
1057 
1058         int cmd = (status & 0xF0);
1059         int ch = (status & 0x0F);
1060 
1061         int data1;
1062         int data2;
1063         if (data.length > 1)
1064             data1 = data[1] & 0xFF;
1065         else
1066             data1 = 0;
1067         if (data.length > 2)
1068             data2 = data[2] & 0xFF;
1069         else
1070             data2 = 0;
1071 
1072         processMessage(ch, cmd, data1, data2);
1073 
1074     }
1075 
1076     public void processMessage(int ch, int cmd, int data1, int data2) {
1077         synchronized (synth.control_mutex) {
1078             activity();
1079         }
1080 
1081         if (cmd == 0xF0) {
1082             int status = cmd | ch;
1083             switch (status) {
1084             case ShortMessage.ACTIVE_SENSING:
1085                 synchronized (synth.control_mutex) {
1086                     active_sensing_on = true;
1087                 }
1088                 break;
1089             default:
1090                 break;
1091             }
1092             return;
1093         }
1094 
1095         SoftChannel[] channels = synth.channels;
1096         if (ch >= channels.length)
1097             return;
1098         SoftChannel softchannel = channels[ch];
1099 
1100         switch (cmd) {
1101         case ShortMessage.NOTE_ON:
1102             if(delay_midievent != 0)
1103                 softchannel.noteOn(data1, data2, delay_midievent);
1104             else
1105                 softchannel.noteOn(data1, data2);
1106             break;
1107         case ShortMessage.NOTE_OFF:
1108             softchannel.noteOff(data1, data2);
1109             break;
1110         case ShortMessage.POLY_PRESSURE:
1111             softchannel.setPolyPressure(data1, data2);
1112             break;
1113         case ShortMessage.CONTROL_CHANGE:
1114             softchannel.controlChange(data1, data2);
1115             break;
1116         case ShortMessage.PROGRAM_CHANGE:
1117             softchannel.programChange(data1);
1118             break;
1119         case ShortMessage.CHANNEL_PRESSURE:
1120             softchannel.setChannelPressure(data1);
1121             break;
1122         case ShortMessage.PITCH_BEND:
1123             softchannel.setPitchBend(data1 + data2 * 128);
1124             break;
1125         default:
1126             break;
1127         }
1128 
1129     }
1130 
1131     public long getMicrosecondPosition() {
1132         if(pusher_silent)
1133         {
1134             if(synth.weakstream != null)
1135             {
1136                 return (long)((sample_pos  + synth.weakstream.silent_samples)
1137                         * (1000000.0 / samplerate));
1138             }
1139         }
1140         return (long)(sample_pos * (1000000.0 / samplerate));
1141     }
1142 
1143     public void close() {
1144     }
1145 }